<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>

    <link rel="stylesheet" type="text/css" 
      href="/assets/css/straybirds.css" media="screen" />
    <link rel="stylesheet" type="text/css" 
      href="/assets/css/pygments.css" media="screen" />

    <!-- MathJax Section Start -->

    <script type="text/javascript"
    src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
    </script>
    <script>
        MathJax.Hub.Config({
              tex2jax: {
              skipTags: ['script', 'noscript', 'style', 'textarea', 'pre']
              }
        });
        MathJax.Hub.Queue(function() {
            var all = MathJax.Hub.getAllJax(), i;
            for(i=0; i < all.length; i += 1) {
                all[i].SourceElement().parentNode.className += ' has-jax';
            }
        });
    </script>

    <!-- MathJax Section End -->

    <!-- Google Analytics Start-->
    <script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-48100787-1', 'minixalpha.github.io');
  ga('send', 'pageview');

</script>

    <!-- Google Analytics End -->

    <title>Monthly archive for 2014/1</title>
  </head>

  <body>
    <div class="container">
      <header>
        <div class="container">
          <h1>
              <a href="/" title="Home Page"> 潇湘夜雨 </a>
          <span class="github-src">
            <a href ="https://github.com/minixalpha/minixalpha.github.io"
               target="_blank"
               title="Fork me on GitHub">
              <img src="/assets/images/GitHub-Mark-Light-32px.png" alt="">
            </a>
          </span>
          </h1>
        </div>
      </header>

      <aside id="left-side">
        <h2> 分类 </h2>
  <ul class="category-list">
      
            
                <li>
                <a href="/categories/计算机系统"> 计算机系统 (3) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/java"> java (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/技术"> 技术 (5) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/工具"> 工具 (4) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/科研"> 科研 (5) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/生活"> 生活 (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/思想"> 思想 (2) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/c语言"> c语言 (4) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/虚拟机"> 虚拟机 (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/英语"> 英语 (8) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/读书"> 读书 (1) </a>
                </li>
            
      
            
                <li>
                <a href="/categories/源代码阅读"> 源代码阅读 (10) </a>
                </li>
            
      
  </ul>

      </aside>

      <aside id="right-side">
        <h2> 归档 </h2>
  <ul class="archive-list">
    
    
    
        
        
        
        
            
            <li>
                <a href="/2014/05">
                    2014-05 (1)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/04">
                    2014-04 (3)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/03">
                    2014-03 (11)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/02">
                    2014-02 (6)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2014/01">
                    2014-01 (3)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2013/11">
                    2013-11 (10)
                </a>
            </li>

        
        
    
        
        
        
        
    
        
        
        
        
    
        
        
        
        
            
            <li>
                <a href="/2013/10">
                    2013-10 (3)
                </a>
            </li>

        
        
    
  </ul>

      </aside>

      <article>

<div class="post-list">
    <ul>

    <li>
      <div class="post-title">
        <a href="/%E6%80%9D%E6%83%B3/2014/01/13/write_high_quality_program.html"> 如何编写高质量的程序</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2014-01-13</li> 
          <li class="post-category"> 思想 </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>如何编写高质量的程序</h1>

<p>学习任何编程语言都会有一个基本的过程，开始的时候学习基本的语法，然后学习各种库，框架，开始做各种项目。在做项目的过程中，随着代码量的增加，我们会渐渐感到失去对程序的掌控能力，bug开始增加，牵一发而动全身，顾此失彼。这充分说明了编写高质量程序的重要性，这里的“高质量”主要指程序的正确性，可读性，可维护性。</p>

<h2>什么是高质量的程序</h2>

<h3>正确性</h3>

<p>程序正确性的重要程度无需多言，尤其在一些特殊领域，例如芯片制造业，航天业，武器制造业，对程序正确性往往有着极其严格的要求，因为一旦程序出错，代价往往是巨大的。在这些领域，需要使用形式化方法(formal methods)来自动验证程序的正确性，也就是说你需要证明程序的正确性，而不仅仅保证程序在大多数情况下是正确的。在其它领域，对正确性没有这么高要求，形式化方法也不适用，但是我们还是需要使用其它手段，例如测试，code review等等来保证软件的正确性。</p>

<h3>可读性</h3>

<p>可读性可以帮助程序作者理清思路，思路清晰后，程序不容易出错。另外，其它程序员在维护你的代码时，更容易理解你的意思，方便修改bug，方便扩展。</p>

<p>不要浪费自己的时间，更不要浪费别人的时间。</p>

<h3>可维护性</h3>

<p>这里的可维护性主要指程序应对变化的能力。程序在完成基本功能后，可能会发生各种改变：用户需求变了，性能达不到要求需要重新实现算法，等等。一旦程序的一个点发生改变，其它点如果也需要同时手动改变，那么程序会变的不可控制，出bug的机会会增加。想像一下，我们的程序是一个盒子，在添加新功能时，如果只需要把新模块插到一个地方，新模块就可以被系统使用，这样的程序可维护性是很高的。但是如果添加新功能时，需要把原来的程序盒子拆开，其它模块也需要相应修改，才能加入新模块，这样的程序可维护性就很差。</p>
 
        <a href="/%E6%80%9D%E6%83%B3/2014/01/13/write_high_quality_program.html"> Read More ... </a> </br>
      </div>
    </li>

    <li>
      <div class="post-title">
        <a href="/%E6%BA%90%E4%BB%A3%E7%A0%81%E9%98%85%E8%AF%BB/2014/01/24/wsgiref-src-intro.html"> wsgiref 源代码分析</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2014-01-24</li> 
          <li class="post-category"> 源代码阅读 </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>wsgiref 源代码分析</h1>

<h2>wsgiref</h2>

<p><a href="http://docs.python.org/2/library/wsgiref.html">wsgiref</a> 是Python标准库给出的 <a href="http://www.python.org/dev/peps/pep-0333/">WSGI</a> 的参考实现。</p>

<p>WSGI是Python Web 开发中为服务器程序和应用程序设定的标准，满足这一标准的服务器程序和应用程序可以配合使用。我在上一篇博文《<a href="http://blog.csdn.net/on_1y/article/details/18803563">WSGI简介</a>》中对此有详细的介绍。在阅读wsgiref源代码之前，一定要对WSGI有一定了解。</p>

<p>WSGI 在 <a href="http://www.python.org/dev/peps/pep-0333/">PEP 333</a> 中描述，但是只靠阅读PEP 333 可能在理解上还是不够深入，所以阅读官方给出的参考实现是很有必要的。阅读完这份源代码后，不仅有利于对WSGI的理解。而且会让你对服务端程序如何对客户端请求有一个直观的理解，从相对底层的socket监听请求，到上层对HTTP请求的处理。</p>

<p>当然，这只是对WSGI的参考实现，目的是为了描述清楚WSGI，而不是真正用在产品中。如果想对Python Web开发中服务器端的实现有更广泛，更深入的理解，需要进一步阅读Python常用框架的源代码。</p>

<h2>wsgiref 源代码分析</h2>

<p>wsgiref 源代码可以在 <a href="https://pypi.python.org/pypi/wsgiref">pypi wsgiref 0.1.2</a> 下载。另外，我在阅读的过程中作了大量注释，包含模块介绍，调用层次关系，demo的运行结果，等 等，还包含了阅读过程中制作的思维导图。GitHub地址<a href="https://github.com/minixalpha/SourceLearning/tree/master/wsgiref-0.1.2">注释版wsgiref</a>。</p>

<h3>结构</h3>

<p><img src="/assets/blog-images/wsgiref.bmp" alt="wsgiref"></p>

<p>上图描述了wsgiref的所有模块及模块间的调用关系，可以看出，wsgiref有以下模块：</p>

<ul>
<li><p>simple_server<br>
这一模块实现了一个简单的 HTTP 服务器，并给出了一个简单的 demo，运行：</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">python simple_server.py
</code></pre></div></li>
</ul>

<p>会启动这个demo，运行一次请求，并把这次请求中涉及到的环境变量在浏览器中显示出来。</p>

<ul>
<li>handlers<br>
simple_server模块将HTTP服务器分成了 Server 部分和Handler部分，前者负责接收请求，后者负责具体的处理，
其中Handler部分主要在handlers中实现。</li>
<li>headers<br>
这一模块主要是为HTTP协议中header部分建立数据结构。</li>
<li>util<br>
这一模块包含了一些工具函数，主要用于对环境变量，URL的处理。</li>
<li>validate<br>
这一模块提供了一个验证工具，可以用于验证你的实现是否符合WSGI标准。</li>
</ul>

<h3>simple_server</h3>
 
        <a href="/%E6%BA%90%E4%BB%A3%E7%A0%81%E9%98%85%E8%AF%BB/2014/01/24/wsgiref-src-intro.html"> Read More ... </a> </br>
      </div>
    </li>

    <li>
      <div class="post-title">
        <a href="/%E6%8A%80%E6%9C%AF/2014/01/26/wsgi-intro.html"> WSGI 简介</a> </br>
      </div>

      <div class="post-info">
        <ol>
          <li class="post-time">2014-01-26</li> 
          <li class="post-category"> 技术 </li>
        </ol>
      </div>

      <div class="post-preview">
        <h1>WSGI 简介</h1>

<h2>背景</h2>

<p>Python Web 开发中，服务端程序可以分为两个部分，一是服务器程序，二是应用程序。前者负责把客户端请求接收，整理，后者负责具体的逻辑处理。为了方便应用程序的开发，我们把常用的功能封装起来，成为各种Web开发框架，例如 Django, Flask, Tornado。不同的框架有不同的开发方式，但是无论如何，开发出的应用程序都要和服务器程序配合，才能为用户提供服务。这样，服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架，都是不好的。对服务器来说，需要支持各种不同框架，对框架来说，只有支持它的服务器才能被开发出的应用使用。</p>

<p>这时候，标准化就变得尤为重要。我们可以设立一个标准，只要服务器程序支持这个标准，框架也支持这个标准，那么他们就可以配合使用。一旦标准确定，双方各自实现。这样，服务器可以支持更多支持标准的框架，框架也可以使用更多支持标准的服务器。</p>

<p>Python Web开发中，这个标准就是 <em>The Web Server Gateway Interface</em>, 即 <strong>WSGI</strong>. 这个标准在<a href="http://www.python.org/dev/peps/pep-0333/">PEP 333</a>中描述，后来，为了支持 Python 3.x, 并且修正一些问题，新的版本在<a href="http://www.python.org/dev/peps/pep-3333/">PEP 3333</a>中描述。</p>

<h2>WSGI 是什么</h2>

<p>WSGI 是服务器程序与应用程序的一个约定，它规定了双方各自需要实现什么接口，提供什么功能，以便二者能够配合使用。</p>

<p>WSGI 不能规定的太复杂，否则对已有的服务器来说，实现起来会困难，不利于WSGI的普及。同时WSGI也不能规定的太多，例如cookie处理就没有在WSGI中规定，这是为了给框架最大的灵活性。要知道WSGI最终的目的是为了方便服务器与应用程序配合使用，而不是成为一个Web框架的标准。</p>

<p>另一方面，WSGI需要使得middleware（是中间件么？）易于实现。middleware处于服务器程序与应用程序之间，对服务器程序来说，它相当于应用程序，对应用程序来说，它相当于服务器程序。这样，对用户请求的处理，可以变成多个 middleware 叠加在一起，每个middleware实现不同的功能。请求从服务器来的时候，依次通过middleware，响应从应用程序返回的时候，反向通过层层middleware。我们可以方便地添加，替换middleware，以便对用户请求作出不同的处理。</p>
 
        <a href="/%E6%8A%80%E6%9C%AF/2014/01/26/wsgi-intro.html"> Read More ... </a> </br>
      </div>
    </li>


    </ul>
  </div>
</div>


      </article>

      <div class="comments">
        
      </div>


      <footer>
        Copyright (c) minixalpha 2014
      </footer>

    </div>
  </body>
</html>
